import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
import { InjectModel } from "@nestjs/mongoose";
import { Cat, CatDocument } from "./schemas/cat.schema";
import { isValidObjectId, Model } from "mongoose";
import { CreateCatDto } from "./dto/create-cat.dto";
import { UpdateCatDto } from "./dto/update-cat.dto";

/**
 * MongoService
 *
 * MongoDB 业务示例：提供 Cat 集合的基础 CRUD
 */
@Injectable()
export class MongoService {
  constructor(@InjectModel(Cat.name) private readonly catModel: Model<CatDocument>) {}

  /**
   * 获取所有猫咪
   */
  async findAll(): Promise<CatDocument[]> {
    return this.catModel.find().exec();
  }

  /**
   * 根据 ID 查询猫咪
   * @param id MongoDB ObjectId
   */
  async findOne(id: string): Promise<CatDocument> {
    this.assertObjectId(id);

    const cat = await this.catModel.findById(id).exec();
    if (!cat) {
      throw new NotFoundException(`未找到猫咪，id=${id}`);
    }

    return cat;
  }

  /**
   * 创建猫咪
   * @param payload 猫咪属性
   */
  async create(payload: CreateCatDto): Promise<CatDocument> {
    const created = new this.catModel(payload);
    return created.save();
  }

  /**
   * 更新猫咪
   * @param id 猫咪 ID
   * @param payload 更新数据
   */
  async update(id: string, payload: UpdateCatDto): Promise<CatDocument> {
    this.assertObjectId(id);

    const updated = await this.catModel
      .findByIdAndUpdate(id, payload, {
        new: true,
        runValidators: true,
      })
      .exec();

    if (!updated) {
      throw new NotFoundException(`未找到猫咪，id=${id}`);
    }

    return updated;
  }

  /**
   * 删除猫咪
   * @param id 猫咪 ID
   */
  async remove(id: string): Promise<void> {
    this.assertObjectId(id);

    const result = await this.catModel.findByIdAndDelete(id).exec();
    if (!result) {
      throw new NotFoundException(`未找到猫咪，id=${id}`);
    }
  }

  /**
   * 校验 ObjectId
   */
  private assertObjectId(id: string) {
    if (!isValidObjectId(id)) {
      throw new BadRequestException(`无效的 MongoDB ObjectId: ${id}`);
    }
  }
}
